﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Automation;
using mshtml;

namespace Noria.Core
{
    public class TDocument
    {
        private AutomationElement m_hDlg;
        private AutomationElement m_host;
        private IHTMLDocument2 m_doc;

        private TDocument(AutomationElement hDlg, AutomationElement host, IHTMLDocument2 doc)
        {
            m_hDlg = hDlg;
            m_host = host;
            m_doc = doc;
        }

        public static TDocument FromTitle(string title)
        {
            foreach (AutomationElement ie in GetIEWindows())
            {
                AutomationElement host = GetShellDocObjectViewFromIE(ie);
                IHTMLDocument2 doc = GetDomFromShellDocObjectView(host.Current.NativeWindowHandle);

                if (title == null || title == String.Empty || doc.title == title)
                {
                    return new TDocument(ie, host, doc);
                }
                else
                {
                    Marshal.ReleaseComObject(doc);
                }
            }

            return null;
        }

        public AutomationElement[] GetActiveXElements(string className)
        {
            if (m_host != null)
                return m_host.GetNativeChildren(className).ToArray();
            else
                return null;
        }


        private static IHTMLDocument2 GetDomFromShellDocObjectView(int hWnd)
        {
            object dom = new object();
            Guid riid = new Guid("626FC520-A41E-11CF-A731-00A0C9082637");
            string lpString = "WM_HTML_GETOBJECT";
            int wMsg = NativeMethods.RegisterWindowMessageA(ref lpString);
            if (wMsg == 0)
            {
                throw new Exception("Unable to register windows message in getDOMFromHwnd()");
            }
            int lResutl = NativeMethods.SendMessageA(hWnd, wMsg, 0, 0);
            if (NativeMethods.ObjectFromLresult(lResutl, ref riid, 0, out dom) != 0)
            {
                throw new Win32Exception("Unable to get IE DOM from window message result in GetDomFromShellDocObjectView()");
            }
            return (IHTMLDocument2)dom;
        }
        private static AutomationElement GetShellDocObjectViewFromIE(AutomationElement ie)
        {
            AutomationElement e = null;

            while (e == null)
                e = ie.FindFirst(TreeScope.Descendants,
                        new PropertyCondition(AutomationElement.ClassNameProperty, "Internet Explorer_Server"));

            return e;
        }
        private static IEnumerable GetIEWindows()
        {
            return AutomationElement.RootElement.GetNativeChildren("IEFrame");
        }

    }
}
